#include "ringBuffer.h"

#undef MIN
#define MIN(a,b) ((a) > (b)?(b):(a))

#define RING_MIN_EXTEND_LEN 16U
#define RING_MAX_EXTEND_LEN 4096U

/*环形缓冲区相关结构体*/
struct ringBuf_t {
	volatile uint32_t r_head;/*缓冲区头部*/
	volatile uint32_t r_tail;/*缓冲区尾部*/
	uint32_t          usrLen;/*用户定义缓冲区的长度*/
	uint8_t           *pUsrBuf;/*指向用户定义缓冲区的指针*/

	volatile uint32_t f_head;
	volatile uint32_t f_tail;
	uint32_t          f_len;/*存储数据帧长度的缓冲区长度*/
	uint32_t          aFrameLen[];/*存储收到数据帧的长度*/
};

static inline bool is_power_of_2(uint32_t n);

static inline bool is_power_of_2(uint32_t n)
{
	return ((n != 0) && ((n & (n - 1)) == 0));
}

uint32_t RingBufInit(struct ringBuf_t **_ringBuf, uint8_t *pBuf, const uint32_t len)
{
	struct ringBuf_t *ringBuf = NULL;
	if(!is_power_of_2(len)) { return 0; }

	ringBuf = (struct ringBuf_t *)malloc(sizeof(struct ringBuf_t) + RING_MIN_EXTEND_LEN * sizeof(uint32_t));
	if(!ringBuf)
	{
		return 0;
	}
	*_ringBuf = ringBuf;
	
	ringBuf->r_head = 0;
	ringBuf->r_tail = 0;
	if(pBuf)
	{
		ringBuf->pUsrBuf = pBuf;
	}
	else
	{
		ringBuf->pUsrBuf = NULL;
		ringBuf->pUsrBuf = (uint8_t *)malloc(len * sizeof(uint8_t));
		if(!ringBuf->pUsrBuf)
		{
			free(*_ringBuf);
			*_ringBuf = NULL;
			
			return 0;
		}
	}
	ringBuf->usrLen = len;
	memset(ringBuf->pUsrBuf,0,len);
	ringBuf->f_head = 0;
	ringBuf->f_tail = 0;
	ringBuf->f_len = RING_MIN_EXTEND_LEN;
	memset(ringBuf->aFrameLen,0,ringBuf->f_len * sizeof(uint32_t));

	return 1;
}

uint32_t RingWriteDataToBuffer(struct ringBuf_t **_ringBuf, const uint8_t *pBuf, const uint32_t len)
{
	struct ringBuf_t *ringBuf = *_ringBuf;
	if(ringBuf == NULL) { return 0; }
	if(pBuf == NULL) { return 0; }
	if(len == 0) { return 0; }
	//如果不能存下此帧，则舍弃
	if(len > ringBuf->usrLen - (ringBuf->r_tail - ringBuf->r_head)) { return 0; }

	//帧长无法存入
	if(1 > ringBuf->f_len - (ringBuf->f_tail - ringBuf->f_head))
	{
		struct ringBuf_t *ring_new = ringBuf;

		/*达到最大扩展长度*/
		if(ringBuf->f_len == RING_MAX_EXTEND_LEN)
		{
			return 0;
		}

		ring_new = (struct ringBuf_t *)realloc(ring_new,sizeof(struct ringBuf_t) + (ringBuf->f_len << 1) * sizeof(uint32_t));
		if(!ring_new)
		{
			return 0;
		}
		ringBuf = *_ringBuf = ring_new;
		//---------------详细参考扩容原理.jpg文件---------------//
		if(ringBuf->f_tail % (ringBuf->f_len << 1) < ringBuf->f_len)
		{
			//----------------------对应情况2----------------------//
			//---------------扩展后搬运数据前内存模型---------------//
			//-----------|***原内存***| |---扩展内存---|-----------//
			//---------------扩展后搬运数据后内存模型---------------//
			//---|***原内存***| |---扩展内存---| |***原内存***|---//
			memcpy(&ringBuf->aFrameLen[ringBuf->f_len + (ringBuf->f_tail % ringBuf->f_len)],&ringBuf->aFrameLen[ringBuf->f_tail % ringBuf->f_len],(ringBuf->f_len - (ringBuf->f_tail % ringBuf->f_len)) * sizeof(uint32_t));
			// 帮助调试
			// memset(&ringBuf->aFrameLen[ringBuf->f_tail % ringBuf->f_len],0,(ringBuf->f_len - (ringBuf->f_tail % ringBuf->f_len)) * sizeof(uint32_t));
		}
		else
		{
			//----------------------对应情况1----------------------//
			//---------------扩展后搬运数据前内存模型---------------//
			//-----------|***原内存***| |---扩展内存---|-----------//
			//---------------扩展后搬运数据后内存模型---------------//
			//---|---扩展内存---| |***原内存***| |---扩展内存---|---//
			memcpy(&ringBuf->aFrameLen[ringBuf->f_len],&ringBuf->aFrameLen[0],(ringBuf->f_tail % ringBuf->f_len) * sizeof(uint32_t));
			// 帮助调试
			// memset(&ringBuf->aFrameLen[0],0,(ringBuf->f_tail % ringBuf->f_len) * sizeof(uint32_t));
		}
		ring_new->f_len <<= 1;
	}
	/*存储桢长*/
	ringBuf->aFrameLen[ringBuf->f_tail % ringBuf->f_len] = len;
	ringBuf->f_tail++;

	//计算写入位置
	uint32_t off = ringBuf->r_tail & (ringBuf->usrLen - 1);
	/*
	*写入数据
	*如果剩余空间未跨首尾相接的地方，则一次写入，否则分两次写入
	*/
	uint32_t min = MIN(len, ringBuf->usrLen - off);
	memcpy(&(ringBuf->pUsrBuf[off]), pBuf, min);
	memcpy(&(ringBuf->pUsrBuf[0]), pBuf + min, len - min);
	ringBuf->r_tail += len;

	return 1;
}

uint32_t RingReadDataFromBuffer(struct ringBuf_t **_ringBuf, uint8_t *pBuf, const uint32_t len)
{
	struct ringBuf_t *ringBuf = *_ringBuf;
	if(ringBuf == NULL) { return 0; }
	if(pBuf == NULL) { return 0; }
	if(len == 0) { return 0; }
	//无数据可读
	if(ringBuf->r_tail == ringBuf->r_head) { return 0; }

	//无帧可读
	if(ringBuf->f_tail == ringBuf->f_head) { return 0; }
	//读取桢长
	uint32_t rd_len = ringBuf->aFrameLen[ringBuf->f_head % ringBuf->f_len];
	//存在内存越界风险
	if(rd_len > len) { return 0; }
	ringBuf->f_head++;

	uint32_t off = ringBuf->r_head & (ringBuf->usrLen - 1);
	/*
	*读取数据
	*如果剩余空间未跨首尾相接的地方，则一次读出，否则分两次读出
	*/
	uint32_t min = MIN(rd_len, ringBuf->usrLen - off);
	memcpy(pBuf, &(ringBuf->pUsrBuf[off]), min);
	memcpy(pBuf + min, &(ringBuf->pUsrBuf[0]), rd_len - min);
	ringBuf->r_head += rd_len;

	return rd_len;
}

void RingBufDestroy(struct ringBuf_t **_ringBuf)
{
	struct ringBuf_t *ringBuf = *_ringBuf;
	
	free(ringBuf->pUsrBuf);
	ringBuf->pUsrBuf = NULL;
	free(ringBuf);
	ringBuf = NULL;
}
